local skynet = require "skynet"

local MJCONST =  require "const"
local WIKTYPE = MJCONST.WIKTYPE
require  "tablelogic"


local CMD={}
local GAMECMD = require "game_proto"

local TableFrameSink = {tabAddr={}}
local Manager=nil
local Chairs = {}

local nPlayerCount = 0

local gJu = 1

function send_data(addr,msg)
    skynet.send(addr,"lua","send_data",msg)
end

function TableFrameSink:InitChair(num)
    TableLogic:InitChair(num)
end

function TableFrameSink:RegisterFun()    
    self.DoMsgList = {}
    self.DoMsgList[GAMECMD.Sub_ClientToGameSvr_TableModle_StandUpReq]       = {UnPackFormat = '',  Func = TableLogic.StandUp}
    self.DoMsgList[GAMECMD.Sub_ClientToGameSvr_TableModle_OutCardReq]       = {UnPackFormat = 'B', Func = TableLogic.OnOutCard}
    self.DoMsgList[GAMECMD.Sub_ClientToGameSvr_TableModle_DoAnGangReq]      = {UnPackFormat = 'B', Func = TableLogic.DoActionReq,     Type = WIKTYPE.WIK_ANGANG}
    self.DoMsgList[GAMECMD.Sub_ClientToGameSvr_TableModle_CanelAnGangReq]   = {UnPackFormat = '',  Func = TableLogic.CancelActionReq, Type = WIKTYPE.WIK_ANGANG}
    self.DoMsgList[GAMECMD.Sub_ClientToGameSvr_TableModle_DoJiaGangReq]     = {UnPackFormat = 'B', Func = TableLogic.DoActionReq,     Type = WIKTYPE.WIK_JIAGANG}
    self.DoMsgList[GAMECMD.Sub_ClientToGameSvr_TableModle_CanelJiaGangReq]  = {UnPackFormat = '',  Func = TableLogic.CancelActionReq, Type = WIKTYPE.WIK_JIAGANG}
    self.DoMsgList[GAMECMD.Sub_ClientToGameSvr_TableModle_CanelJieGangReq]  = {UnPackFormat = '',  Func = TableLogic.CancelActionReq, Type = WIKTYPE.WIK_JIEGANG}
    self.DoMsgList[GAMECMD.Sub_ClientToGameSvr_TableModle_CanelPengReq]     = {UnPackFormat = '',  Func = TableLogic.CancelActionReq, Type = WIKTYPE.WIK_PENG}
    self.DoMsgList[GAMECMD.Sub_ClientToGameSvr_TableModle_DoJieGangReq]     = {UnPackFormat = 'B', Func = TableLogic.DoActionReq,     Type = WIKTYPE.WIK_JIEGANG}
    self.DoMsgList[GAMECMD.Sub_ClientToGameSvr_TableModle_DoPengReq]        = {UnPackFormat = 'B', Func = TableLogic.DoActionReq,     Type = WIKTYPE.WIK_PENG}
    
    self.DoMsgList[GAMECMD.Sub_ClientToGameSvr_TableModle_DoDuGangReq]      = {UnPackFormat = 'B', Func = TableLogic.DoActionReq,     Type = WIKTYPE.WIK_DU}
    
    self.DoMsgList[GAMECMD.Sub_ClientToGameSvr_TableModle_DoHuReq]          = {UnPackFormat = 'B', Func = TableLogic.DoActionReq,     Type = WIKTYPE.WIK_HU}
    self.DoMsgList[GAMECMD.Sub_ClientToGameSvr_TableModle_CancelHuReq]      = {UnPackFormat = '',  Func = TableLogic.CancelActionReq, Type = WIKTYPE.WIK_HU}
    
    self.DoMsgList[GAMECMD.Sub_ClientToGameSvr_TableModle_DoChiReq]         = {UnPackFormat = 'BBB', Func = TableLogic.DoActionReq,   Type = WIKTYPE.WIK_LINE}
    self.DoMsgList[GAMECMD.Sub_ClientToGameSvr_TableModle_CanelChiReq]      = {UnPackFormat = '',  Func = TableLogic.CancelActionReq, Type = WIKTYPE.WIK_LINE}
    
    self.DoMsgList[GAMECMD.Sub_ClientToGameSvr_TableModle_FanJiangOrNot]    = {UnPackFormat = 'B',  Func = TableLogic.ProcFanJiangOrNot}
    self.DoMsgList[GAMECMD.Sub_ClientToGameSvr_TableModle_LiaoLongOrNot]    = {UnPackFormat = 'B',  Func = TableLogic.ProcLiaoLongOrNot}
    self.DoMsgList[GAMECMD.Sub_ClientToGameSvr_TableModle_MaiZhuangOrNot]   = {UnPackFormat = 'B',  Func = TableLogic.ProcMaiZhuangOrNot}
    
    self.DoMsgList[GAMECMD.Sub_ClientToGameSvr_TableModle_WantFaceReq]      = {UnPackFormat = 'I4',  Func = TableLogic.WantFaceReq}
    self.DoMsgList[GAMECMD.Sub_ClientToGameSvr_TableModle_WantVoiceReq]     = {UnPackFormat = 'I4',  Func = TableLogic.WantShortVoiceReq}  -- 发送内置的短语言
    self.DoMsgList[GAMECMD.Sub_ClientToGameSvr_TableModle_SendTxtReqs]      = {UnPackFormat = 'I4c256',  Func = TableLogic.SendTextReq}
    
    
    TableLogic:RegisterFun()
end


function TableFrameSink.GetPlayerTableChair(Player)
    local play_id,chair_id,tabel_id=skynet.call(Manager,"lua","GetPlayerTableChair",Player)
    return play_id,chair_id,tabel_id
end

function TableFrameSink:OnStandUpReq(smsg, Player)
    local chair = TableLogic:PlayerToChair(Player)
    TableLogic:StandUp(chair)
    
    --[[reload_module("tablelogic")
    TableLogic:InitChair(nPlayerCount)
    for chair in TableLogic:ChairIterator() do     --重新填充地址
        chair.addr = TableFrameSink.tabAddr[chair.UserChairID]
        TableLogic.chairAddr[chair.addr] = chair
    end]]--
end

function TableFrameSink:OnGameStart()  
    print('OnGameStart!!!!!!!!!!!!!!!!!')
    TableLogic:InitChair(nPlayerCount)
    TableLogic:MakeReadyTable()
    TableLogic:OnGameStart()
end


function TableFrameSink:StartFaPai(wJu)
    TableLogic:StartFaPai(wJu)
end


function TableFrameSink:DispatchCard()    --摸牌
    TableLogic:DispatchCard()
end

function TableFrameSink:BroadCastOutCard()
    TableLogic:BroadCastOutCard()
end

function TableFrameSink:DoMsg(act, smsg, Player)
    local chair = TableLogic:PlayerToChair(Player)
    if chair then 
        local reciever = TableLogic
        if act.Reciever then reciever = act.Reciever end
        if act.UnPackFormat == '' then 
            act.Func(reciever, chair, act.Type)
        else
            if act.Type then 
                 act.Func(reciever, chair, act.Type, string.unpack(act.UnPackFormat, smsg))
            else act.Func(reciever, chair, string.unpack(act.UnPackFormat, smsg))
            end
        end
        
    end
end

function TableFrameSink:OnGameMsg(scmd, smsg, Player)
    local data = string.sub(smsg, 5)
    local act = self.DoMsgList[scmd]
    if act then 
       self:DoMsg(act, data, Player) 
    end
end

function CMD.OnSitDownSucess(Player)
    local GAME_ID = tonumber(skynet.getenv('game_id')) or 1001 
    local msg = string.pack(">I2>I2<I4<I4", 303, 2070, GAME_ID, nPlayerCount)    --再告诉客户端几人麻将
    send_data(Player.nAgentAddr, msg)
        
    local i = 1
    repeat
        local chairAct = TableLogic:GetChair(i)
        if chairAct and not chairAct.addr then      --椅子还没有被占用,绑定地址
            --TableLogic.TableObj.m_pChairs[chairAct.UserChairID].Player = Player
            chairAct.addr = Player.nAgentAddr
            chairAct.PlayerId = Player.nPlayerId
            --TableFrameSink.tabAddr[chairAct.UserChairID] = Player.nAgentAddr
            TableLogic.chairAddr[chairAct.addr] = chairAct
            --TableFrameSink:OnSitDownSucess(Player)
            return chairAct.UserChairID
        end
        i = i + 1
    until i > nPlayerCount
end

function CMD.SetTableData(Table, nMaxPlayerCount, nDiFen, nMa, nFangPaoOrZiMo, nDianPaoMaOrZiMoMa, nKeQiangGang, externData)
    TableFrameSink:InitChair(nMaxPlayerCount)
    TableFrameSink:RegisterFun()
    TableLogic.TableObj = Table
    TableLogic.TableId = Table.m_nTableId
    print("*******SetTableData tabId is ", Table.m_nTableId or 0)
    local cpDes = TableLogic:SetTableData(externData)
    nPlayerCount = nMaxPlayerCount 
    local strMakeRoomMsg = '南通长牌 '..cpDes
    TableLogic.DiFen = nDiFen
    local num = nMaxPlayerCount
    for chair_id = 0 , num - 1 do 
        Table.m_pChairs[chair_id].m_isValid = 1
    end
    if num == 2 then 
        Table.m_pChairs[1].m_isValid = 0
        Table.m_pChairs[2].m_isValid = 1
    end
    
    return strMakeRoomMsg ,Table
end


function CMD.OnPlayerOfflineBack(Player, ChairId)
    local chair = TableLogic:UserIdToChair(ChairId)
    chair.addr = Player.nAgentAddr                          --重新获得地址
    TableLogic.chairAddr[chair.addr] = chair
    TableLogic:SendMeOfflineBackData(Player, ChairId)
end


function CMD.OnEventGameStart(Table, itableframe)
    if Table.m_wCurJu == 1 then 
        TableLogic.TableObj = Table
        TableLogic.ItableSrv = itableframe
    end
    TableFrameSink:OnGameStart()
end

function CMD.OnUserGoOnGameReq(chair_id)
    TableLogic:OnUserGoOnGame(chair_id)
end

function CMD.TrySitDown(Player)
    local i = 1
    repeat
        local chairAct = TableLogic:GetChair(i)
        if chairAct and not chairAct.addr then      --椅子还没有被占用,绑定地址
            chairAct.addr = Player.nAgentAddr
            TableFrameSink.tabAddr[chairAct.UserChairID] = Player.nAgentAddr
            TableLogic.chairAddr[chairAct.addr] = chairAct
            TableFrameSink:OnSitDownSucess(Player)
            return chairAct.UserChairID
        end
        i = i + 1
    until i > nPlayerCount
end

function CMD.ConcluedGameLastRound()
    TableLogic:ConcluedGameLastRound()
    return true
end

function CMD.OneJuOver(TableObj)
    TableLogic:OneJuOver(TableObj)
end

function CMD.OnGameMessage(scmd,smsg,Player)
     skynet.error("[tableframe]",scmd)
     TableFrameSink:OnGameMsg(scmd, smsg, Player)
end

function CMD.ConcludeGame(...)
    TableLogic:ConcludeGame(...)
end

function CMD.CloseTableFrame()
    skynet.exit()
end

skynet.start(function()
    skynet.error("tableframe server start...")
	skynet.dispatch("lua", function(_,_, command, ...)
		local f = CMD[command]
		skynet.ret(skynet.pack(f(...)))
	end)
    Manager=skynet.localname(".manager")
    math.randomseed(os.time())
end)